package main

import (
	"context"
	"log"

	"gitee.com/yanwc/ebicycle/device/internal/codec"
	"gitee.com/yanwc/ebicycle/device/internal/field"
	"gitee.com/yanwc/ebicycle/device/internal/uppacket"
	"gitee.com/yanwc/ebicycle/device/server"

	"github.com/panjf2000/gnet"
)

func main() {
	echo := new(Server)
	log.Fatal(gnet.Serve(echo, "tcp://127.0.0.1:9899", gnet.WithMulticore(true), gnet.WithCodec(&codec.BikeFrameCodec{})))
}

type Server struct {
	gnet.EventServer
}

func (es *Server) OnClosed(c gnet.Conn, err error) (action gnet.Action) {
	imei := c.Context().(context.Context).Value("imei").(field.IMEI)
	if d, ok := server.SessionDevices.Get(imei); !ok {
		return gnet.Close
	} else if &d.Conn == &c {
		server.SessionDevices.Remove(imei)
	}
	return gnet.Close
}

func (es *Server) React(packet []byte, c gnet.Conn) (out []byte, action gnet.Action) {
	fh := &codec.Frame{}
	err := fh.UnWrapPacket(packet)
	if !fh.CRCCheck() {
		return nil, gnet.None
	}

	if err != nil {
		log.Fatal(err)
	}

	if v, ok := uppacket.Packets[fh.CmdWord.Uint8()]; ok {
		if r, action, err := v.Do(fh, c); err != nil {
			return r, gnet.Shutdown
		} else {
			return r, action
		}
	} else {
		log.Fatalf("命令字%d不支持,数据帧:%#v", fh.CmdWord, fh.RawData())
	}

	return fh.WrapPacket(nil), gnet.Shutdown
}
